

#include "audio_core.h"

#ifdef __AUDIO_SDL__

#include <assert.h>
#include <sstream>

using namespace WtfAudio;
using namespace std;

/**
 * Constructor. Note that 'name' is not the filename, rather it is a description
 * for use in debug messages.
 **/
AudioSample::AudioSample(const WtfEngine::String& name) : DataObject(name) {
	if (NULL == AudioMixer::GetInstancePtr())
		Log(LOG_ERROR, "Creating an audio sample when the mixer has not been started!");

	loaded = false; Data = NULL;
}

// Destructor; free the sample data
AudioSample::~AudioSample() {
	if (loaded)
		Mix_FreeChunk(this->Data);
}

// Load an audio file from the specified path
AudioSample * AudioSample::Load(const WtfEngine::String& sFilePath) {
	AudioSample * pSample = new AudioSample(sFilePath);
	
	pSample->Data = Mix_LoadWAV(sFilePath.c_str());
	if (pSample->Data != NULL)
	{
		pSample->Log(LOG_INFO, WtfEngine::String("Loaded sample ") + sFilePath + " ok.");
		pSample->loaded = true;
	} else {
		throw std::runtime_error(WtfEngine::String("Failed to load audio sample: ") + sFilePath);
	}
	
	return pSample;
}

void AudioSample::Play() {
	if (isLoaded()) {
		this->channel = Mix_PlayChannel(-1, this->Data, 0);
		if (this->channel == -1) {
			Log(LOG_WARNING, "");
		}
	} else {
		Log(LOG_WARNING, "Attempting to play sample that hasn't been loaded!");
	}
}

// Set the volume of the sample. It can range from 0.0 (silent) to 1.0 (max)
void AudioSample::setVolume(double volume) {
	assert(volume >= 0.0); assert(volume <= 1.0);
	Mix_VolumeChunk(this->Data, (int)(volume*MIX_MAX_VOLUME));

	ostringstream logmsg;
	logmsg << "Set volume of audio sample to " << volume;
	Log(LOG_INFO, logmsg.str());
}



/* * * * * * * * * */
/* The Audio Mixer */
/* * * * * * * * * */

/** Constructor; initialize SDL_mixer */
AudioMixer::AudioMixer() : WtfEngine::Loggable<AudioMixer>("Audio Mixer") {
	int freq = 44100; 						// Sampling Frequency
	Uint16 sampleFormat = AUDIO_S16SYS; // Output signed 16-bit samples
	int channels = 2; 						// Stereo
	int chunkSize = 1024; 					// 1Kb chunks

	// Attempt to open mixer for output
	if (Mix_OpenAudio(freq, sampleFormat, channels, chunkSize) < 0) {
		ostringstream logmsg;
		logmsg << "Error opening audio mixer: " << SDL_GetError();
		Log(LOG_ERROR, logmsg.str());
	} else {
		Log(LOG_INFO, "Opened audio mixer successfully.");
	}
}

/** Destructor; shut down SDL_mixer */
AudioMixer::~AudioMixer() {
	Log(LOG_INFO, "Shutting down audio mixer");
	Mix_CloseAudio();
}









TestSample::TestSample() : AudioSample() {
	Load("media/sounds/test.wav");
}


#endif
